package com.xayy.health.core.utils;

import cn.hutool.core.collection.CollUtil;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author zhangxa
 */
public class ListUtil {
    /**
     * 指定长度分组
     */
    public static <T> List<List<T>> partition(List<T> list, int chunkSize) {
        return IntStream.range(0, (list.size() + chunkSize - 1) / chunkSize)
                .mapToObj(i -> list.subList(i * chunkSize, Math.min((i + 1) * chunkSize, list.size())))
                .collect(Collectors.toList());
    }

    /**
     * 数据叠加求和
     */
    public static <T> int sumField(List<T> list, String fieldName) {
        int sum = 0;
        if (CollectionUtils.isEmpty(list)) {
            return sum;
        }
        for (T item : list) {
            try {
                java.lang.reflect.Field field = item.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                if (field.get(item) != null) {
                    sum += (int) field.get(item);
                }

            } catch (NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return sum;
    }

    /**
     * 寻找重复值（指定string类型）
     */
    public static List<String> findDuplicate(List<String> list) {

        ArrayList<String> arrayList = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return arrayList;
        }
        Map<String, Integer> map = new HashMap<>(50);
        for (String code : list) {
            if (map.containsKey(code)) {
                arrayList.add(code);
            } else {
                map.put(code, 1);
            }
        }
        return arrayList;
    }

    /**
     * 寻找重复值(任意类型)
     */
    public static <T> List<T> findDuplicateOther(List<T> list) {
        ArrayList<T> arrayList = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return arrayList;
        }
        Map<T, Integer> map = new HashMap<>(50);
        for (T code : list) {
            if (map.containsKey(code)) {
                arrayList.add(code);
            } else {
                map.put(code, 1);
            }
        }
        return arrayList;
    }

    /**
     * 数据补全
     */
    public static <T> List<Object> getChangeMap(List<String> xAxis, List<T> list) throws Exception {
            List<Object> finalList = new ArrayList<>();
            if (CollUtil.isNotEmpty(xAxis)) {
                for (String xAxi : xAxis) {
                    boolean found = false;
                    List<Object> arrayList = new ArrayList<>();
                    if (CollUtil.isNotEmpty(list)) {
                        for (T array : list) {
                            if (array instanceof List) {
                                List listArray = (ArrayList) array;
                                if (listArray.get(0).equals(xAxi)) {
                                    arrayList.add(xAxi);
                                    arrayList.add(listArray.get(1));
                                    found = true;
                                    finalList.add(arrayList);
                                    break;
                                }
                            } else {
                                if (array.getClass().getDeclaredField("time").getName().equals(xAxi)) {
                                    arrayList.add(xAxi);
                                    arrayList.add(array.getClass().getDeclaredField("value").getName());
                                    found = true;
                                    finalList.add(arrayList);
                                    break;
                                }
                            }

                        }
                    }
                    if (!found) {
                        arrayList.add(xAxi);
                        arrayList.add(null);
                        finalList.add(arrayList);
                    }
                }
            } else {
                finalList = new ArrayList<>();
            }
            return finalList;
    }
}